package com.xiaoshuidi.cloud.module.finance.util.invoice;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.dtflys.forest.annotation.JSONBody;
import com.dtflys.forest.annotation.Post;
import com.xiaoshuidi.cloud.module.finance.bwclient.RestClient;
import com.xiaoshuidi.cloud.module.finance.bwclient.pojo.FpChCreate;
import com.xiaoshuidi.cloud.module.finance.bwclient.pojo.FpCreate;
import com.xiaoshuidi.cloud.module.finance.bwclient.pojo.Signfptb;
import com.xiaoshuidi.cloud.module.finance.enums.invoice.BwServiceEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;

/**
 * @author dujianguang
 */
@Component
@Slf4j
public class BwServiceUtil {

    private static RestClient restClient;
    @Autowired
    private RestClient client;

    @PostConstruct
    public void init() {
        restClient = this.client;
    }

    /**
     * appid
     */
    private static String appid;

    @Value("${qdfp.appid}")
    public void setAppid(String appid) {
        BwServiceUtil.appid = appid;
    }

    /**
     * 签名方式
     */
    private static String signType;

    @Value("${qdfp.signType}")
    public void setSignType(String signType) {
        BwServiceUtil.signType = signType;
    }

    /**
     * secret
     */
    private static String secret;

    @Value("${qdfp.secret}")
    public void setSecret(String secret) {
        BwServiceUtil.secret = secret;
    }

    private static String yhdm;

    @Value("${qdfp.yhdm}")
    public void setYhdm(String yhdm) {
        BwServiceUtil.yhdm = yhdm;
    }

    private static String bmdm;

    @Value("${qdfp.bmdm}")
    public void setBmdm(String bmdm) {
        BwServiceUtil.bmdm = bmdm;
    }

    private static String kpzddm;

    @Value("${qdfp.kpzddm}")
    public void setKpzddm(String kpzddm) {
        BwServiceUtil.kpzddm = kpzddm;
    }

    private static String kpy;

    @Value("${qdfp.kpy}")
    public void setKpy(String kpy) {
        BwServiceUtil.kpy = kpy;
    }

    private static String gsdm;

    @Value("${qdfp.gsdm}")
    public void setGsdm(String gsdm) {
        BwServiceUtil.gsdm = gsdm;
    }

    /**
     * 发票申请
     */
    public static String fpCreate(FpCreate fpCreate) {
        fpCreate.setGsdm(gsdm);
        fpCreate.setBmdm(bmdm);
        fpCreate.setYhdm(yhdm);
        fpCreate.setKpzddm(kpzddm);
        fpCreate.setKpy(kpy);
        String content = JSONUtil.toJsonStr(fpCreate);
        Signfptb signfptb = fillQdfpParam(BwServiceEnum.FP_CREATE.getServiceCode(), content);
        String result = restClient.qdfp(JSONUtil.toJsonStr(signfptb));
        return result;
    }


    /**
     * 发票结果查询
     */
    public static String fpStatusSearch(Map<String, String> map) {
        String content = JSONUtil.toJsonStr(map);
        Signfptb signfptb = fillQdfpParam(BwServiceEnum.FP_STATUS_SEARCH.getServiceCode(), content);
        String result = restClient.qdfp(JSONUtil.toJsonStr(signfptb));
        return result;
    }


    /**
     * 发票冲红申请
     */
    public static String fpChCreate(FpChCreate fpChCreate) {
        String content = JSONUtil.toJsonStr(fpChCreate);
        Signfptb signfptb = fillQdfpParam(BwServiceEnum.FP_CH_CREATE.getServiceCode(), content);
        String result = restClient.qdfp(JSONUtil.toJsonStr(signfptb));
        return result;
    }


    /**
     * 发票冲红申请结果查询
     */
    public static String fpChStatusSearch(Map<String, String> map) {
        String content = JSONUtil.toJsonStr(map);
        Signfptb signfptb = fillQdfpParam(BwServiceEnum.FP_CH_STATUS_SEARCH.getServiceCode(), content);
        String result = restClient.qdfp(JSONUtil.toJsonStr(signfptb));
        return result;
    }

    /**
     * 发票冲红确认单状态查询
     */
    public static String fpChConfirmStatusSearch(Map<String, String> map) {
        String content = JSONUtil.toJsonStr(map);
        Signfptb signfptb = fillQdfpParam(BwServiceEnum.FP_CH_CONFIRM_STATUS_SEARCH.getServiceCode(), content);
        String result = restClient.qdfp(JSONUtil.toJsonStr(signfptb));
        return result;
    }


    /**
     * 发票冲红开具结果查询
     */
    public static String fpChKjStatusSearch(Map<String, String> map) {
        String content = JSONUtil.toJsonStr(map);
        Signfptb signfptb = fillQdfpParam(BwServiceEnum.FP_CH_KJ_STATUS_SEARCH.getServiceCode(), content);
        String result = restClient.qdfp(JSONUtil.toJsonStr(signfptb));
        return result;
    }


    /**
     * 含税金额计算
     */
    public static BigDecimal hsjeCal(BigDecimal bhsje, Double tax) {
        return bhsje.multiply(new BigDecimal("1").add(new BigDecimal(tax))).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 税额
     */
    public static BigDecimal seCal(BigDecimal bhsje, Double tax) {
        return bhsje.multiply(new BigDecimal(tax)).setScale(2, BigDecimal.ROUND_HALF_UP);
    }


    /**
     * 封装数电接口请求体
     *
     * @param serviceId 不同业务不同值，具体可以看文档
     * @param content   报文content数据
     * @return
     */
    public static Signfptb fillQdfpParam(String serviceId, String content) {
        log.info("数电发票 content {}", content);
        Signfptb signfptb = new Signfptb();
        signfptb.setAppid(appid);
        signfptb.setSignType(signType);
        signfptb.setContent(Base64Util.encode(content));
        signfptb.setServiceid(serviceId);
        String signature = "";
        // 签名值计算
        switch (signType) {
            case "0":
                signature = HMACSHA256Util.sha256_HMAC("appid=" + appid + "&" + "content=" + Base64Util.encode(content) + "&" + "serviceid=" + serviceId, secret);
                break;
            case "1":
                signature = MD5Util.getMd5(appid + secret + Base64Util.encode(content) + serviceId);
                break;
            case "3":
                signature = "";
                break;
            default:
                throw new RuntimeException("签名类型错误");
        }
        signfptb.setSignature(signature);
        return signfptb;
    }

    /**
     * 从文件中读取json数据
     *
     * @param fileName
     * @return
     */
    public String readFileToStr(String fileName) {
        try {
            File file = ResourceUtils.getFile("classpath:invoicefile/" + fileName);
            return FileUtils.readFileToString(file, "UTF-8");
        } catch (FileNotFoundException e) {
            log.error("获取文件失败");
        } catch (IOException e) {
            log.error("获取文件失败");
        }
        return null;
    }


}
